package org.xdq.反射机制;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

public class Test {
    public static void main(String[] args) throws ClassNotFoundException, IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException {
        Class c = null;
        //Class被称为元类，是描述类的类，元类的每一个对象描述一个Java类

        //如何获取Class的对象，默认情况下无论何种方式获得的描述同一个类的元类对象，都是同一个对象
        Class c1 = Student.class;//获取了描述Student类的元类对象
        Class c2 = new Student().getClass();//通过对象获得对象所属类的元类对象
        Class c3 = Class.forName("org.xdq.反射机制.Student");//通过类全限定名的字符串获得类元类对象

        System.out.println(c1==c2);

        //元类对象可以干什么
        //1.通过元类对象可以获得所描述类的实际对象
        Object obj = c1.newInstance();//获得了Student对象
        System.out.println(obj);

        //2.通过元类对象可以获得所描述类的全限定名称和简称
        String name = c1.getName();//全限定名称
        System.out.println(name);
        String simpleName = c1.getSimpleName();//简称
        System.out.println(simpleName);

        //3. 通过元类对象可以获得所描述类的public方法的反射对象（描述方法的类Method的对象）
        Method md1 = c1.getMethod("getStuName");
        Method md2 = c1.getMethod("setStuName", String.class);

        //执行方法
        md2.invoke(obj, "小明");
        System.out.println(((Student)obj).getStuName());
        Object returnVal = md1.invoke(obj);
        System.out.println(returnVal);

        //获得方法名称
        System.out.println(md2.getName());

        //获得方法的参数定义
        Class[] types = md2.getParameterTypes();
        for(Class type:types){
            System.out.println(type.getName());
        }

        //获得参数的数量
        System.out.println(md2.getParameterCount());

        //获得返回值类型
        System.out.println(md2.getReturnType().getName());

        //System.out.println(Character.isUpperCase('中'));

        System.out.println(Character.isLetter('总'));

        System.out.println(Character.isAlphabetic('中'));

    }
}
